package com.pan.download5.driver;

import com.pan.crawler.Directory;
import com.pan.crawler.Page;
import com.pan.download5.ctrl.*;
import com.pan.entity.BookDirectory;
import com.pan.entity.Chapter;

import java.util.List;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

public class BasicDriver implements Driver {

    private Class<? extends Page> pageClass;
    private Class<? extends Directory> directoryClass;

    public BasicDriver(Class<? extends Page> pageClass,Class<? extends Directory> directoryClass) {

        this.pageClass = pageClass;
        this.directoryClass = directoryClass;
    }



    private <T> T getInstance(Class<? extends T> clazz){
        try {
            T instance = clazz.getConstructor().newInstance();
            return instance;
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }
    private Page getPageInstance(){
        return getInstance(pageClass);
    }
    private Directory getDirectoryInstance(){
        return getInstance(directoryClass);
    }

    @Override
    public void run(String url, int threadCount) {
        Directory directory = getDirectoryInstance();
        BookDirectory bookDirectory = directory.get(url);
        List<Chapter> chapterList = bookDirectory.getChapterList();
        String bookName = bookDirectory.getBookName();
        System.out.println("开始爬取："+bookName);
        TaskSyncPublish taskPublish = new ArrayTaskPublish(chapterList);
        ChapterSyncWriter chapterSyncWriter = new ChapterSyncWriterImpl(bookName);
        chapterSyncWriter.start();
        CountDownLatch countDownLatch = new CountDownLatch(threadCount);
        ThreadPoolExecutor poolExecutor = new ThreadPoolExecutor(threadCount, threadCount,
                //这三个参数在这里是无关紧要的,因为线程数量是固定的任务数量是固定的。
                114514, TimeUnit.MILLISECONDS, new ArrayBlockingQueue<>(10));
        for (int i = 0; i < threadCount; i++) {
            Runnable taskHandle = new TaskHandleImpl(getPageInstance(),
                    taskPublish, chapterSyncWriter,countDownLatch);
            poolExecutor.execute(taskHandle);
        }
        try {
            countDownLatch.await();
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
        chapterSyncWriter.close();
        poolExecutor.shutdown();
        System.out.println("爬取完成："+bookName+"!");
    }


}
